package com.weir.oauth2.config;

import javax.sql.DataSource;

import com.weir.oauth2.authority.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.provisioning.JdbcUserDetailsManager;

// 配置授权中心信息
//@Configuration
//@EnableAuthorizationServer // 开启认证授权中心
public class AuthorizationServerDBConfig extends AuthorizationServerConfigurerAdapter {
	// accessToken有效期
	private int accessTokenValiditySeconds = 7200; // 两小时
	// 刷新accessToken有效期
	private int refreshTokenValiditySeconds = 7200; // 两小时

	@Autowired
	private AuthenticationManager authenticationManager;

	@Autowired
	@Qualifier("dataSource")
	private DataSource dataSource;

	@Bean
	public TokenStore tokenStore() {
		// return new InMemoryTokenStore(); //使用内存中的 token store
		return new JdbcTokenStore(dataSource); /// 使用Jdbctoken store
	}

	// 添加商户信息
	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		// 申请获取appid和appkey
		clients.jdbc(dataSource);
		// 初始化
//		  .withClient("weir2").secret(passwordEncoder().encode("123456"))
//		  .authorizedGrantTypes("password", "client_credentials",
//		  "refresh_token","authorization_code")
//		  .scopes("all").redirectUris("http://www.loveweir.com")
//		  .accessTokenValiditySeconds(accessTokenValiditySeconds)
//		  .refreshTokenValiditySeconds(refreshTokenValiditySeconds);
		 
		// withClient appid
//		clients.inMemory().withClient("weir").secret(passwordEncoder().encode("123456"))
//				.authorizedGrantTypes("authorization_code")
////				.authorizedGrantTypes("password", "client_credentials", "refresh_token", "authorization_code")
//				.scopes("all").redirectUris("http://www.loveweir.com")
//				.accessTokenValiditySeconds(accessTokenValiditySeconds)
//				.refreshTokenValiditySeconds(refreshTokenValiditySeconds);
	}

	// 设置token类型
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
		endpoints.authenticationManager(authenticationManager).allowedTokenEndpointRequestMethods(HttpMethod.GET,
				HttpMethod.POST);

		endpoints.authenticationManager(authenticationManager);
		endpoints.userDetailsService(userDetailsService());
	}

	@Override
	public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
		// 允许表单认证
		oauthServer.allowFormAuthenticationForClients();
		// 允许check_token访问
		oauthServer.checkTokenAccess("permitAll()");
	}

	@Bean
	AuthenticationManager authenticationManager() {
		AuthenticationManager authenticationManager = new AuthenticationManager() {
			@Override
			public Authentication authenticate(Authentication authentication) throws AuthenticationException {
				return daoAuhthenticationProvider().authenticate(authentication);
			}
		};
		return authenticationManager;
	}

	@Bean
	public AuthenticationProvider daoAuhthenticationProvider() {
		DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
		daoAuthenticationProvider.setUserDetailsService(userDetailsService());
		daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
		daoAuthenticationProvider.setPasswordEncoder(passwordEncoder());
		return daoAuthenticationProvider;
	}

	// 设置添加用户信息,正常应该从数据库中读取
	@Bean
	UserDetailsService userDetailsService() {
		InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();

		userDetailsService.createUser(User.withUsername("weir1").password(passwordEncoder().encode("123456"))
				.authorities("ROLE_111").build());
		userDetailsService.createUser(User.withUsername("weir2").password(passwordEncoder().encode("1234567"))
				.authorities("ROLE_USER").build());

		return userDetailsService;
	}

	@Bean
	PasswordEncoder passwordEncoder() {
		// 加密方式
		PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
		return passwordEncoder;
	}

}
